/**
basic syntax of a lambda:

[capture list] (parameter list) mutable(optional) exception attribute -> return type {
    //function body
}

capture list can be understood as a type of parameter.
the capture list can server to transfer external data.

capture list classes"
value capture
reference capture
implicit capture
expression capture
*/

#include <iostream>
#include <memory>


void lambda_value_capture();
void lambda_reference_capture();
void lambda_expression_capture();

using namespace std;
int main() {
    
    lambda_value_capture();
    lambda_reference_capture();
    lambda_expression_capture();

    return 0;
}

void lambda_value_capture() {
    int value = 1;
    auto copy_value = [value] {
        return value;
    };
    value = 100;
    auto stored_value = copy_value();
    cout << "stored_value:"<<stored_value<<", value:"<<value <<endl;
}
void lambda_reference_capture() {
    int value = 1;
    auto copy_value = [&value] {
        return value;
    };
    value = 100;
    auto stored_value = copy_value();
    cout << "stored_value:"<<stored_value<<", value:"<<value <<endl;
}

void lambda_expression_capture() {
    auto important = make_unique<int>(1);
    auto add = [v1 = 1, v2 = move(important)](int x, int y) -> int {
        return x+y+v1+(*v2);
    };
    cout << add(3,4) << endl;
}